package model

import (
	"encoding/base64"
	"fmt"
	"time"

	"github.com/axengine/utils/hash"
	"github.com/vmihailenco/msgpack/v5"
)

type Model struct {
	ID        int32     `gorm:"primarykey" json:"id"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
	//DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}

const (
	RuleSetKey = "RuleSetKey"
	RuleBlock  = 0
	RulePass   = 1
)

type App struct {
	Model
	AppName  string `gorm:"comment:应用名称;type:VARCHAR(255)"`
	AppId    string `gorm:"comment:应用ID;type:VARCHAR(64);uniqueIndex:IDX_APP_DEV"`
	DeviceId string `gorm:"comment:设备ID;type:VARCHAR(64);uniqueIndex:IDX_APP_DEV"`
	Memo     string `gorm:"comment:备注;type:VARCHAR(255)"`
	UserId   string `gorm:"comment:用户ID;type:VARCHAR(64);uniqueIndex:IDX_APP_DEV"`
}

func (a *App) Key() string {
	return "app" + "_" + a.AppId + "_" + a.DeviceId + "_" + a.UserId
}

func (a *App) Value() string {
	bz, err := msgpack.Marshal(a)
	if err != nil {
		panic(err)
	}
	return base64.StdEncoding.EncodeToString(bz)
}

type Rule struct {
	Model
	AppId    string `gorm:"comment:应用ID;type:VARCHAR(32);uniqueIndex:IDX_DEV_APP_DST"`
	DeviceId string `gorm:"comment:设备ID;type:VARCHAR(32);uniqueIndex:IDX_DEV_APP_DST"`
	DstIP    string `gorm:"comment:目的IP;type:VARCHAR(32);uniqueIndex:IDX_DEV_APP_DST"`
	DstPort  string `gorm:"comment:目的端口;type:VARCHAR(32);uniqueIndex:IDX_DEV_APP_DST"`
	Status   int    `gorm:"comment:状态 0-禁用 1-启用;type:TINYINT(4)"`
	UserId   string `gorm:"comment:用户id;type:VARCHAR(32);uniqueIndex:IDX_DEV_APP_DST"`
}

func (r *Rule) Key() string {
	return hash.MD5Lower([]byte(fmt.Sprintf("%s%s%s%s%s",
		r.DeviceId, r.AppId, r.DstIP, r.DstPort, r.UserId)))
}

type Whitelist struct {
	Model
	AppName  string `gorm:"comment:应用名称;type:VARCHAR(255)"`
	AppId    string `gorm:"comment:应用ID;type:VARCHAR(64);uniqueIndex:IDX_APP_DEV"`
	DeviceId string `gorm:"comment:设备ID;type:VARCHAR(64);uniqueIndex:IDX_APP_DEV"`
	Memo     string `gorm:"comment:备注;type:VARCHAR(255)"`
}

func (w *Whitelist) Key() string {
	return "whitelist" + "_" + w.AppId + "_" + w.DeviceId
}

func (w *Whitelist) Value() string {
	bz, err := msgpack.Marshal(w)
	if err != nil {
		panic(err)
	}
	return base64.StdEncoding.EncodeToString(bz)
}

type Warning struct {
	ID        int32     `gorm:"primarykey" json:"id"`
	CreatedAt time.Time `json:"createdAt"`
	AppName   string    `gorm:"comment:应用名称;type:VARCHAR(255);index"`
	AppId     string    `gorm:"comment:应用ID;type:VARCHAR(64);index:IDX_APP_DEV"`
	DeviceId  string    `gorm:"comment:设备ID;type:VARCHAR(64);index:IDX_APP_DEV"`
	Memo      string    `gorm:"comment:设备备注;type:VARCHAR(255)"`
	DstIP     string    `gorm:"comment:目的IP;type:VARCHAR(32);index"`
	DstPort   int       `gorm:"comment:目的端口;type:INT(11);index"`
	Desc      string    `gorm:"comment:备注;type:VARCHAR(255)"`
	Level     int       `gorm:"comment:等级;type:INT(11)"`
}
